package com.huey.utils.aop;

import cn.hutool.core.exceptions.ExceptionUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.math3.geometry.euclidean.oned.Interval;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;

import static com.fasterxml.jackson.databind.type.LogicalType.DateTime;

/**
 * 处理SDK远程调用 远端服务返回错误码问题

 * @version 1.0
 * @author: LuoGuang
 * @date 2020-05-26 17:01
 * @Package com.glxytech.cloud.cost.aop
 */
@Component
@Aspect
@Log4j2
public class SdkApiReturnAspect {


    /**
     * 返回正常code码
     */
    private static final String SUCCESS_CODE = "0";

    /**
     * message KEY
     */
    private static final String MESSAGE_KEY = "getMsg";

    /**
     * 状态码 KEY
     */
    private static final String CODE_KEY = "getCode";
    @Pointcut("execution (* com.huey.utils..*.api.*.*(..))")
    public void apiSdkAop() {
    }

    /**
     * 判断远程服务返回状态码是否正常，不正常则抛出异常
     *
     * @param
     * @param point
     * @return
     * @author LuoGuang
     * @version 1.0
     * @date 2020/5/26 17:19
     */
    @Around("apiSdkAop()")
    public Object aroundApi(ProceedingJoinPoint point) throws Throwable {
        UUID uuid = UUID.randomUUID();
        String uid = uuid.toString();
        Object response = null;


        Class<?> targetCls = point.getTarget().getClass();
        MethodSignature ms = (MethodSignature) point.getSignature();
        String targetClsName = targetCls.getName();
        String targetObjectMethodName = targetClsName + "." + ms.getName();

        printRequestLog(uid, targetObjectMethodName, point.getArgs());

        Long startTime =System.currentTimeMillis();
        Long endTime;
        Interval interval;

        try {
            response = point.proceed();
        } catch (Exception e) {
//            String msg = "远程调用标识【"+uid+"】远程"+targetObjectMethodName+"服务异常【"+ ExceptionUtil.getMessage(e) +"】";
//            if(e instanceof ApiException){
//                log.error("ApiException服务异常【" + ((ApiException)e).getResponseBody() +"】");
//            }
//            throw new ApplicationException(msg);
            String title = "远程调用标识【" + uid + "】远程" + targetObjectMethodName
                    + "服务异常【" + ExceptionUtil.getMessage(e) + "】";
/*            BaseSentryException baseSentryException = new BaseSentryException("500", "系统发生异常", title, e.getStackTrace());
            throw baseSentryException;*/
        } finally {
            endTime =System.currentTimeMillis();
            interval = new Interval(startTime, endTime);
        //    log.info("\n\n 远程调用标识【{}】\n 返回结果响应内容【{}】 \n 响应时间【{}毫秒】\n", uid, LogPrintFilterUtils.filter(JSON.toJSONString(response)), interval.toDurationMillis());
        }
        Class<?> aClass = response.getClass();
        Method getPayload = aClass.getMethod(CODE_KEY);
        Object payLoad = getPayload.invoke(response);
        String code = payLoad.toString();
        if (!SUCCESS_CODE.equals(code)) {
            Method getMsg = aClass.getMethod(MESSAGE_KEY);
            Object msg = getMsg.invoke(response);
            String exceptionMsg = "无响应msg";
            if (msg != null) {
                exceptionMsg = msg.toString();
            }
/*            ApplicationException exception = new ApplicationException(exceptionMsg);
            exception.setCode(code);
            throw exception;*/
        }
        return response;
    }


    private void printRequestLog(String uid, String targetObjectMethodName, Object[] args) {
        JSONArray argsJsonArray = new JSONArray(Arrays.asList(args));
        //log.info("\n\n 远程调用标识【{}】\n 类方法【{}】\n 参数【{}】\n", uid, targetObjectMethodName, LogPrintFilterUtils.filter(argsJsonArray.toJSONString()));
    }
}
